package com.shuyuwl.core.controller;

import com.shuyuwl.core.support.ServerResponse;
import com.shuyuwl.core.domain.AbstractBaseDomain;
import com.shuyuwl.core.repository.DaoRepository;
import com.shuyuwl.core.service.IDaoService;
import com.shuyuwl.core.vo.BaseVO;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.Serializable;

/**
 * 该类主要是RestController 的抽象类，继承该类需要通过泛型传入相关信息：实体类、VO（值对象）、 主键类型、Repository接口类、Service接口类
 * 所有增删改查Controller基类，子类可覆盖add、remove、modify、get方法实现抽象方法，完成增删改查功能
 * /{subclass request mapping}            POST ==> add() 新增对象
 * /{subclass request mapping}/{id}       DELETE ==> remove() 删除单个对象
 * /{subclass request mapping}/{id}       PUT ==> modify() 修改对象信息
 * /{subclass request mapping}/{id}       GET ==> get() 获取当个对象信息
 * @Author ZChao
 * @Date 2019/9/16
 **/
public abstract class AbstractRestController<T extends AbstractBaseDomain, V extends BaseVO, ID extends Serializable, R extends DaoRepository<T, ID>, S extends IDaoService<T, ID, R>> extends BaseController {

    @Autowired
    protected S service;

    @PostMapping
    @ApiOperation(value = "增加方法")
    protected ServerResponse<V> addWrapper(@RequestBody V vo, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse){
        this.httpServletRequest = httpServletRequest;
        this.httpServletResponse = httpServletResponse;

        vo = this.add(vo);
        return ServerResponse.createBySuccess(vo);
    }

    /**
     * add 抽象方法
     * @param vo VO对象
     * @return
     */
    protected abstract V add(V vo);

    @DeleteMapping("/{id}")
    @ApiOperation(value = "删除方法")
    @ApiImplicitParams({@ApiImplicitParam(name = "id", paramType = "path", value = "主键ID", example = "1")})
    protected ServerResponse<V> removeWrapper(@PathVariable("id") ID id, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse){
        this.httpServletRequest = httpServletRequest;
        this.httpServletResponse = httpServletResponse;

        this.remove(id);
        return ServerResponse.createBySuccess();
    }

    /**
     * remove 抽象方法
     * @param id
     */
    protected abstract void remove(ID id);

    @PutMapping("/{id}")
    @ApiOperation(value = "修改方法")
    @ApiImplicitParams({@ApiImplicitParam(name = "id", paramType = "path", value = "主键ID",example = "1"),
            @ApiImplicitParam(format = "form", name = "vo")})
    protected ServerResponse<V> modifyWrapper(@PathVariable("id") ID id, @RequestBody V vo, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse){
        this.httpServletRequest = httpServletRequest;
        this.httpServletResponse = httpServletResponse;

        vo = this.modify(id, vo);
        return ServerResponse.createBySuccess(vo);
    }

    /**
     * modify 抽象方法
     * @param id
     * @param vo 需要修改的VO对象
     * @return
     */
    protected abstract V modify(ID id, V vo);

    @GetMapping("/{id}")
    @ApiOperation(value = "根据ID获取实体")
    @ApiImplicitParam(name = "id", paramType = "path", value = "主键ID", example = "1")
    protected ServerResponse<V> getWrapper(@PathVariable("id") ID id, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse){
        this.httpServletRequest = httpServletRequest;
        this.httpServletResponse = httpServletResponse;

        V vo = this.get(id);
        return ServerResponse.createBySuccess(vo);
    }

    /**
     * get 抽象方法
     * @param id 主键ID
     * @return
     */
    protected abstract V get(ID id);
}
